package com.yuang.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

@Service
public class AccountService  {
    @Autowired
    private AccountDao accountDao;

    //同时建立username与缓存结果,id与缓存结果,hight与缓存结果的关联，
    //这样下次如果按照id查找直接从缓存中就命中了
    //key的策略可以参考 https://blog.csdn.net/l1028386804/article/details/70946410?locationNum=12&fps=1
    /*
    @Caching(
            cacheable  ={@Cacheable(value = "account",key = "#userName")},
            put = {
                    @CachePut(value = "user", key = "#result.id", condition = "#result != null"),
                    @CachePut(value = "user", key = "#result.hight", condition = "#result != null")
            }
    )
    */

    @Cacheable(value = "account",key="#userName")
    public Account getAccountByName(String userName) {
        System.out.println("AccountService.getAccountName() was called");
        return accountDao.getAccountByName(userName);
    }

    //spring cache的限制，内部调用不会走缓存
    public Account getAccountFromInternal(String userName) {
        System.out.println("AccountService.getAccountFromInternal() was called");
        return getAccountByName(userName);
    }

    @Cacheable(value = "account",key="#userName")
    public Account readAccountName(String userName) {
        System.out.println("AccountService.readAccountName() was called");
        return accountDao.getAccountByName(userName);
    }

    //只缓存name长度<=4的acount
    @Cacheable(value = "account",key="#userName", condition ="#userName.length() <=4" )
    public Account getAccountByCondition(String userName) {
        System.out.println("AccountService.getAccountByCondition()");
        return accountDao.getAccountByName(userName);
    }

    //使用多个参数组合成key
    @Cacheable(value = "account",key="#userName.concat(#id)")
    public Account getAccountByIdAndName(int id,String userName,boolean other) {
        System.out.println("AccountService.getAccountByIdAndName()");
        return accountDao.getAccountByName(id,userName);
    }

    @CacheEvict(value="account",key="#account.getName()")
    public void updateAcount(Account account) {
        System.out.println("AccountService.updateAcount() was called");
        accountDao.updateAccount(account);
    }

    //可以即更新数据同时又更新缓存
    @CachePut(value = "account", key="#account.getName()")
    public void updateDBAndCache(Account account){
        System.out.println("AccountService.updateDBAndCache() was called");
        accountDao.updateAccount(account);
    }



    @CacheEvict(value = "account", allEntries = true)
    public void reload(){

    }

    //beforeInvocation = true使得在方法执行前就清空缓存，保存缓存一定能清空
    @CacheEvict(value = "account",allEntries = true, beforeInvocation = true)
    public void reloadAnyway() {
        throw new NullPointerException();
    }
}
